﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Serialization;
using Telerik.Windows.Controls;
using Telerik.Windows.Data;

namespace ForexTester
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private int quantity = 0;
        private decimal spread=0;
        private decimal buyStart = 0;
        private decimal sellStart = 0;
        private int increase = 0;
        private int decrease = 0;
        private  delegate void refreshGridDelegate();
        private bool isRunning = false;

        public MainWindow()
        {
            switch (ForexTester.Properties.Settings.Default.TelerikTheme)
            {
                case "Office_Black":
                    StyleManager.ApplicationTheme = new Office_BlackTheme();
                    break;
                case "Office_Blue":
                    StyleManager.ApplicationTheme = new Office_BlueTheme();
                    break;
                case "Office_Silver":
                    StyleManager.ApplicationTheme = new Office_SilverTheme();
                    break;
                case "Expression_Dark":
                    StyleManager.ApplicationTheme = new Expression_DarkTheme();
                    break;
                case "Summer":
                    StyleManager.ApplicationTheme = new SummerTheme();
                    break;
                case "Vista":
                    StyleManager.ApplicationTheme = new VistaTheme();
                    break;
                case "Windows7":
                    StyleManager.ApplicationTheme = new Windows7Theme();
                    break;
                case "Transparent":
                    StyleManager.ApplicationTheme = new TransparentTheme();
                    break;
                case "Windows8":
                    StyleManager.ApplicationTheme = new Windows8Theme();
                    break;
                case "Windows8Touch":
                    StyleManager.ApplicationTheme = new Windows8TouchTheme();
                    break;
            }
            InitializeComponent();
            this.RadComboBoxStyle.Text = ForexTester.Properties.Settings.Default.TelerikTheme;
        }

        private void RadGridViewReading_DataLoaded(object sender, EventArgs e)
        {
            ((GridViewDataColumn)this.RadGridViewReading.Columns["ItemNumber"]).AggregateFunctions.Clear();
            ((GridViewDataColumn)this.RadGridViewReading.Columns["ItemNumber"]).AggregateFunctions.Add(new CountFunction() { Caption = "Count:"  });
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Date"]).DataFormatString = " {0:dd/MM/yyyy} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Open"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["High"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["High"]).AggregateFunctions.Clear();
            ((GridViewDataColumn)this.RadGridViewReading.Columns["High"]).AggregateFunctions.Add(new MaxFunction() { Caption = "Max:", SourceField = "High", ResultFormatString = " {0:N4} " });
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Low"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Low"]).AggregateFunctions.Clear();
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Low"]).AggregateFunctions.Add(new MinFunction() { Caption = "Min:", SourceField = "Low", ResultFormatString = " {0:N4} " });
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Close"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["High_Open"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["Open_Low"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewReading.Columns["High_Low"]).DataFormatString = " {0:N4} ";
        }

        private void RadGridViewAnalysis_DataLoaded(object sender, EventArgs e)
        {
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["Quantity"]).AggregateFunctions.Clear();
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["Quantity"]).AggregateFunctions.Add(new CountFunction() { Caption = "Count: "});
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["Spread"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["StartDate"]).DataFormatString = " {0:dd/MM/yyyy HH:mm} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["StartPrice"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["EndDate"]).DataFormatString = " {0:dd/MM/yyyy HH:mm} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["EndPrice"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["ItemProfit"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["TotalProfit"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["PrevouisTrailing"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["ActualProfit"]).DataFormatString = " {0:N4} ";
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["ActualProfit"]).AggregateFunctions.Clear();
            ((GridViewDataColumn)this.RadGridViewAnalysis.Columns["ActualProfit"]).AggregateFunctions.Add(new SumFunction() { Caption = "Sum:", SourceField = "ActualProfit", ResultFormatString = " {0:N4} " });
        }

        private void RadGridViewComplexAnalysis_DataLoaded(object sender, EventArgs e)
        {
            if (this.RadGridViewComplexAnalysis.Columns.Count > 0)
            {
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["ActualProfit"]).DataFormatString = " {0:N4} ";
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["ActualProfit"]).DataFormatString = " {0:N4} ";
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["ActualProfit"]).AggregateFunctions.Clear();
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["ActualProfit"]).AggregateFunctions.Clear();
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["ActualProfit"]).AggregateFunctions.Add(new MaxFunction() { Caption = "Max:", SourceField = "ActualProfit", ResultFormatString = " {0:N4} " });
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["Period"]).AggregateFunctions.Clear();
                ((GridViewDataColumn)this.RadGridViewComplexAnalysis.Columns["Period"]).AggregateFunctions.Add(new CountFunction() { Caption = "Count: " });
            }
        }

        private void RadComboBoxStyle_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.IsLoaded)
            {
                switch (RadComboBoxStyle.Text)
                {
                    case "Office_Black":
                        StyleManager.ApplicationTheme = new Office_BlackTheme();
                        break;
                    case "Office_Blue":
                        StyleManager.ApplicationTheme = new Office_BlueTheme();
                        break;
                    case "Office_Silver":
                        StyleManager.ApplicationTheme = new Office_SilverTheme();
                        break;
                    case "Expression_Dark":
                        StyleManager.ApplicationTheme = new Expression_DarkTheme();
                        break;
                    case "Summer":
                        StyleManager.ApplicationTheme = new SummerTheme();
                        break;
                    case "Vista":
                        StyleManager.ApplicationTheme = new VistaTheme();
                        break;
                    case "Windows7":
                        StyleManager.ApplicationTheme = new Windows7Theme();
                        break;
                    case "Transparent":
                        StyleManager.ApplicationTheme = new TransparentTheme();
                        break;
                    case "Windows8":
                        StyleManager.ApplicationTheme = new Windows8Theme();
                        break;
                    case "Windows8Touch":
                        StyleManager.ApplicationTheme = new Windows8TouchTheme();
                        break;
                }
                ForexTester.Properties.Settings.Default.TelerikTheme = this.RadComboBoxStyle.Text;
                ForexTester.Properties.Settings.Default.Save();
                MainWindow item = new MainWindow();
                App.Current.MainWindow = item;
                item.Show();
                this.Close();
            }
        }

        private void RadButtonIn_Click(object sender, RoutedEventArgs e)
        {
            this.RadTabControl.SelectedIndex = 0;
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            if (dlg.ShowDialog() == true)
            {
                this.TextBoxIn.Text = dlg.FileName;
                var marketItems = PerformTrading.ReadFile(this.TextBoxIn.Text);
                this.RadNumericUpDownBuyStart.Value = (double)marketItems[0].Open;
                this.RadNumericUpDownSellStart.Value = (double)marketItems[0].Open;
                this.RadGridViewReading.ItemsSource = marketItems;
            }
        }

        private void RadButtonOut_Click(object sender, RoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            if (dlg.ShowDialog() == true)
            {
                this.TextBoxOut.Text = dlg.FileName;
                using (FileStream file = new FileStream(dlg.FileName, FileMode.Open))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(List<Statistic>));
                    var StatisticItems = (List<Statistic>)serializer.Deserialize(file);
                    this.RadTabControl.SelectedIndex = 2;
                    this.RadGridViewComplexAnalysis.ItemsSource = StatisticItems;
                }
            }
        }


        private void RadButtonAnalysis_Click(object sender, RoutedEventArgs e)
        {
            this.RadTabControl.SelectedIndex = 1;
            if (this.TextBoxIn.Text.Trim() != "")
            {
                var marketItems = PerformTrading.ReadFile(this.TextBoxIn.Text);
                this.RadGridViewAnalysis.ItemsSource = PerformTrading.Analyze(marketItems, (decimal)this.RadNumericUpDownBuyStart.Value.Value, (decimal)this.RadNumericUpDownSellStart.Value.Value,(int)this.RadNumericUpDownIncrease.Value.Value,(int)this.RadNumericUpDownDecrease.Value.Value,(int)this.RadNumericUpDownTakeProfit.Value.Value, (int)this.RadNumericUpDownStoploss.Value.Value, (int)this.RadNumericUpDownTrailingstop.Value.Value, (int)this.RadNumericUpDownQuantity.Value.Value, (decimal)this.RadNumericUpDownSpread.Value.Value).OrderBy(i => i.StartDate);
            }
            else
            {
                MessageBox.Show("choose input file");
            }
        }

        private void RadButtonComplexAnalysis_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                this.RadTabControl.SelectedIndex = 2;
                if (this.TextBoxIn.Text.Trim() != "")
                {
                    if (this.TextBoxOut.Text.Trim() != "")
                    {
                        if (!this.isRunning)
                        {
                            this.isRunning = true;
                            this.RadButtonComplexAnalysis.Content = "Stop";
                            PerformTrading.ThreadCounts = (int)this.RadNumericUpDownThreadCounts.Value.Value;
                            PerformTrading.FilePath = this.TextBoxOut.Text;
                            var marketItems = PerformTrading.ReadFile(this.TextBoxIn.Text);
                            this.quantity = (int)this.RadNumericUpDownQuantity.Value.Value;
                            this.spread = (decimal)this.RadNumericUpDownSpread.Value.Value;
                            this.buyStart=(decimal)this.RadNumericUpDownBuyStart.Value.Value;
                            this.sellStart=(decimal)this.RadNumericUpDownSellStart.Value.Value;
                            this.increase=(int)this.RadNumericUpDownIncrease.Value.Value;
                            this.decrease=(int)this.RadNumericUpDownDecrease.Value.Value;
                            Thread t = new Thread(this.startComplexAnalysis);
                            t.IsBackground = true;
                            t.Start(marketItems);
                            Thread t2 = new Thread(this.refreshUILoop);
                            t2.IsBackground = true;
                            t2.Start();
                        }
                        else
                        {
                            PerformTrading.StopComplexAnalysis();
                            this.isRunning = false;
                            this.RadButtonComplexAnalysis.Content = "Start";
                        }
                    }
                    else
                    {
                        MessageBox.Show("choose output file");
                    }
                }
                else
                {
                    MessageBox.Show("choose input file");
                }
            }
            catch (Exception er)
            {
                MessageBox.Show(er.ToString());
            }
        }
        
        private void startComplexAnalysis(object obj)
        {
            var marketItems = (List<Market>)obj;
            PerformTrading.StartComplexAnalysis(marketItems, this.quantity, this.spread,this.buyStart,this.sellStart,this.increase,this.decrease);
            this.isRunning = false;
        }
        private void refreshUILoop()
        {
            while (this.isRunning)
            {
                try
                {
                    this.Dispatcher.Invoke(this.refreshUI, System.Windows.Threading.DispatcherPriority.Background);
                    Thread.Sleep(5000);
                }
                catch
                {
                }
            }
            this.Dispatcher.Invoke(this.refreshUI, System.Windows.Threading.DispatcherPriority.Background);
        }
        private void refreshUI()
        {
            try
            {
                this.RadGridViewComplexAnalysis.ItemsSource = null;
                this.RadGridViewComplexAnalysis.ItemsSource = PerformTrading.CurrentStatisticItems.Where(i => i != null).OrderByDescending(i => i.ActualProfit);
                this.LabelProgress.Content = "Enterance: " + PerformTrading.CurrentEnterance + " Stop: " + PerformTrading.CurrentStopLoss + " Trailing: " +
                    PerformTrading.CurrentTrailingStop + " Profit: " + PerformTrading.CurrentTakeProfit + " IterationPerSeconds: " + PerformTrading.IterationsPerSeconds +
                    " Remainingtime: " + TimeSpan.FromSeconds(((100 * 100 * 100 * 100)  - (PerformTrading.CurrentEnterance / 50 * PerformTrading.CurrentStopLoss / 50 * PerformTrading.CurrentTrailingStop / 50 * PerformTrading.CurrentTakeProfit / 50))/ PerformTrading.IterationsPerSeconds).ToString()
                    +" curentthreadCounts: "+PerformTrading.currentThreadCounts;
                this.RadButtonComplexAnalysis.Content = this.isRunning ? "Stop" : "Start";
            }
            catch(Exception er)
            {
            }
        }

    }
}
